Emit E_PROVISION_CONFLICT for uv sync resolution conflicts - #6479
Emit E_PROVISION_CONFLICT for uv sync resolution conflicts#6479rugpanov wants to merge 1 commit into
Conversation
Approval status: pending
|
| // keeps. Gating on the merge signal rather than uv's stderr keeps the code | ||
| // precise: it fires only when a conflict the CLI itself detected is present. | ||
| // | ||
| // The warning means the merged pins are provably unsatisfiable, so a real |
There was a problem hiding this comment.
If we already know the pins are unsatisfiable why do we wait for uv sync to fail? Why not error right away?
There was a problem hiding this comment.
Good call — now we error right away.
7d3ec5f to
f9ffddd
Compare
e6fe8cd to
dc380a0
Compare
`databricks environments setup-local` wrapped every provisioning failure as E_PROVISION. The extension's recovery flow needs to tell a dependency version conflict — the project's dependencies can't be satisfied against the pins this command wrote for the target environment — apart from a generic failure it can't fix by relaxing constraints. The merge phase already detects a provable version conflict and records it as the W_USER_CONSTRAINT_CONFLICT warning. When that fires, uv sync would deterministically fail to resolve, so report the new E_PROVISION_CONFLICT right after writing the project files (diskMutated=true, at the provision phase) instead of spending a doomed Python install and sync. Gating on the CLI's own detection keeps the code precise — no uv-stderr matching and no false positive on an unrelated sync failure. Adds the matching telemetry enum value and its coverage case, a unit test asserting the fail-fast path reports the conflict without invoking provisioning, and an acceptance golden. Co-authored-by: Isaac <no-reply@databricks.com>
dc380a0 to
6c07a2b
Compare
Integration test reportCommit: 6c07a2b
Top 6 slowest tests (at least 2 minutes):
|
Why
databricks environments setup-localwrapped every provisioning failure asE_PROVISION. The VPEX extension's recovery flow needs to distinguish adependency version conflict — the project's dependencies can't be satisfied
against the pins this command wrote for the target environment — from a generic
failure it can't fix by relaxing constraints (a build-backend error, a permissions
problem, a transport error). Fixes DECO-28365.
What
E_PROVISION_CONFLICT(libs/localenv/result.go), reportedfrom the provision phase.
user's dependencies and the environment pins and records it as the
W_USER_CONSTRAINT_CONFLICTwarning (libs/localenv/warnings.go, PEP 440interval math on provably-disjoint ranges, scanning every requirement uv locks).
uv syncwould deterministically fail to resolve,so the pipeline fails fast: right after the merge writes the project files it
reports
E_PROVISION_CONFLICT(failurePhase=provision,diskMutated=true)without attempting the Python install or
uv sync(
libs/localenv/pipeline.go,hasConstraintConflictWarning). Every otherprovisioning failure keeps
E_PROVISION.the code precise — no false positive on an unavailable package or an
unrelated sync failure — and needs no brittle stderr matching.
diskMutated=trueis preserved because the constraints are written before the check, which the
extension's recovery flow relies on.
--dry-runis unchanged: it computes a plan and does not evaluate provisioning,so the same conflict surfaces there as the
W_USER_CONSTRAINT_CONFLICTwarning(
ok=true) — a test pins that intended divergence.SetupLocalErrorCodeProvisionConflictand the mapping case(
cmd/environments/telemetry.go,libs/telemetry/protos/setup_local.go), keptexhaustive by the linter and
TestErrorCodeCoversLocalenv.Consumer-facing note
Adding
E_PROVISION_CONFLICTis additive, but this exact scenario previouslysurfaced as
E_PROVISION. Any consumer that special-casedE_PROVISIONfor theconflict case will see the new code. The universe lumberjack proto should add the
matching
SetupLocalErrorCodeenum value (ingestion ignores unknown values, so thetwo changes can land in either order).
Testing
libs/localenv/pipeline_test.go): a conflict warning makes the runreport
E_PROVISION_CONFLICTat the provision phase withdiskMutated=trueandwithout invoking Python install or sync (
recordingPMrecords neither);--dry-runwith the same pins reportsok=truewith the warning and no error,writing nothing.
TestPipelineRetainsFallbackResolutionWhenProvisioningFailsstill covers a generic sync failure →
E_PROVISION.acceptance/localenv/provision-conflict/): a realsetup-localrun where the user pins
pip==24.0and the remote constraints pinpip<24; themerge flags the conflict and the command reports
E_PROVISION_CONFLICTbeforeprovisioning. Cross-platform (only preflight
uv --versionruns; the doomed syncnever does), so it runs on every OS with no fake binary.
gofmt,go vet,golangci-lint, and the localcheck-changelogpass.This pull request and its description were written by Isaac.